package com.jy.framework.config.json;

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Set;

public class MyBeanSerializerModifier extends BeanSerializerModifier {

    private JsonSerializer<Object> _nullArrayJsonSerializer = new MyNullArrayJsonSerializer();
    private JsonSerializer<Object> _nullStringJsonSerializer = new MyNullStringJsonSerializer();
    private JsonSerializer<Object> _nullNumberJsonSerializer = new MyNullNumberJsonSerializer();
    private JsonSerializer<Object> _nullDateJsonSerializer = new MyDateStringJsonSerializer();

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
                                                     List<BeanPropertyWriter> beanProperties) {
        // 循环所有的beanPropertyWriter
        for (int i = 0; i < beanProperties.size(); i++) {
            BeanPropertyWriter writer = beanProperties.get(i);
            rewriteNull(writer);
        }
        return beanProperties;
    }

    private void rewriteNull(BeanPropertyWriter writer) {
//        字符串
        JavaType type = writer.getType();
        if (type.hasRawClass(String.class)){
            writer.assignNullSerializer(this._nullStringJsonSerializer);
        }
//数字,BigDecimal 保持默认，可能需要设置为2位小数，也可以在这里统一处理了
        if (type.isTypeOrSubTypeOf(Number.class) && !type.isTypeOrSubTypeOf(BigDecimal.class)){
            writer.assignNullSerializer(this._nullNumberJsonSerializer);
        }

        //日期
        if (type.isTypeOrSubTypeOf(Date.class)) {
            writer.assignNullSerializer(this._nullDateJsonSerializer);
        }


        // 判断字段的类型，如果是array，list，set则注册nullSerializer
        if (isArrayType(writer)) {
            //给writer注册一个自己的nullSerializer
            writer.assignNullSerializer(this._nullArrayJsonSerializer);
        }
    }

    // 判断是什么类型
    protected boolean isArrayType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getPropertyType();
        return clazz.isArray() || clazz.equals(List.class) || clazz.equals(Set.class);

    }

}
